home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / modules / nessus-2.2.8.mo / usr / lib / nessus / plugins / ssh_func.inc < prev    next >
Text File  |  2005-03-31  |  55KB  |  2,036 lines

  1. #TRUSTED 01420b737fc429504d9c57b28a501132f3b4fdd63bfb8f065db5d2e70b9b5bf35d2085e901e3faecea0fa2910fb295b92b2e893f09d84142600a26ef1f9b30f572b8b93b38fb148613e20d19a3822981f12621660d245d4937f91206bcf9287ba30884300a7c705dea0f600b346cc7a5392681620535805ac5f5ae9f4a27c3555bc567b28709cba881f022854ed6c50843413d9379eeac1c619741218a7c6373bc9ea511eda7706fcbd23503e28634814639f6117c109364174715de974f1eaebed27fa7b50f4b16a093a5a6c26a9a32f2fc66725f46f6319384c9dbdce1e7f2cb94c8a0acf0bc670ed57c7a1725b80a208fd467391a42e31d309088968686ebc1bf43273127370dc539d772c52e9da558a8970183bea7b657265c07850b42e48f6bbd3e2a0fb82068541ade5ded1ab95f747ca6a28a3a13f24e86c73ca13f2e18cfa4af243dabca1049a018046bcec6110ec90b48165697f41575c9d36655c6a36b811f2a0ebf56117adfe0c432c12ac7fe3c50abe39040810257852973e7ef45f91c6c0bae310d38eef3cd3d874e608c1bc419a13e13c1b03a32a8e841b43dfc629679a009fd0862b5e131a3e62e161ad5f98798932d1cee85ef17b17a8917eb8f0dec5bf15c99432d90d8c08c8dbc869dbcd6f7044b9abe0526937f671fa8c1f04774a407af40d21bd28653deee579ea20e5d06c7b4ff0897b80fc53883f7
  2. #------------------------------------------------------------------------------
  3. #
  4. # (C) Nicolas Pouvesle
  5. # This script is released under the version 2 to the Gnu General Public Licence
  6. #
  7. #
  8. # **** You need Nessus 2.1.0 or newer to make any use of the functions in this
  9. # ****  file
  10. #
  11. #
  12.  
  13. global_var session_id, enc_keys, seqn_w, seqn_r;
  14. global_var local_channel, remote_channel;
  15. global_var l_window_size, received_size;
  16. global_var r_window_size, r_packet_size;
  17. global_var dh_pub, dh_priv;
  18. global_var _ssh_banner;
  19. global_var _ssh_server_version;
  20. global_var _ssh_supported_authentication;
  21. global_var _ssh_cmd_error;
  22. global_var _ssh_error;
  23. global_var _reuse_connection;
  24. global_var bugged_sshd, bugged_first, bugged_channels, bugged_rws, bugged_rps;
  25.  
  26.  
  27. # ssh_hex2raw() copied from misc_func.inc as we don't want to taint ssh_func.inc with
  28. # a third-party include
  29. function ssh_hex2raw(s)
  30. {
  31.  local_var i, j, ret, l;
  32.  
  33.  s = chomp(s);  # remove trailing blanks, CR, LF...
  34.  l = strlen(s);
  35.  if (l % 2) display("ssh_hex2raw: odd string: ", s, "\n");
  36.  for(i=0;i<l;i+=2)
  37.  {
  38.   if(ord(s[i]) >= ord("0") && ord(s[i]) <= ord("9"))
  39.         j = int(s[i]);
  40.   else
  41.         j = int((ord(s[i]) - ord("a")) + 10);
  42.  
  43.   j *= 16;
  44.   if(ord(s[i+1]) >= ord("0") && ord(s[i+1]) <= ord("9"))
  45.         j += int(s[i+1]);
  46.   else
  47.         j += int((ord(s[i+1]) - ord("a")) + 10);
  48.   ret += raw_string(j);
  49.  }
  50.  return ret;
  51. }
  52.  
  53.  
  54. function register_int_in_kb(int, name)
  55. {
  56.  if ( ! defined_func("replace_kb_item") || !_reuse_connection ) return 0;
  57.  replace_kb_item(name:name, value:int);
  58. }
  59.  
  60. function load_int_from_kb(name)
  61. {
  62.  if ( ! defined_func("get_kb_fresh_item") || !_reuse_connection ) return NULL;
  63.  return get_kb_fresh_item(name);
  64. }
  65.  
  66. function register_data_in_kb(data, name)
  67. {
  68.  local_var n, item;
  69.  n = 0;
  70.  if ( ! defined_func("replace_kb_item") || !_reuse_connection ) return 0;
  71.  replace_kb_item(name:name, value:hexstr(data));
  72. }
  73.  
  74. function load_data_from_kb(name)
  75. {
  76.  local_var item;
  77.  if ( ! defined_func("get_kb_fresh_item") || !_reuse_connection ) return NULL;
  78.  item =  get_kb_fresh_item(name);
  79.  if ( isnull(item) ) return NULL;
  80.  return ssh_hex2raw(s:item);
  81. }
  82.  
  83. function register_array_in_kb(array, name)
  84. {
  85.  local_var i, item;
  86.  if ( ! defined_func("replace_kb_item") || !_reuse_connection ) return 0;
  87.  for ( i = 0 ; i < max_index(array); i ++ )
  88.  {
  89.   replace_kb_item(name:name + "_" + i, value:hexstr(array[i]));
  90.  }
  91. }
  92.  
  93. function register_intarray_in_kb(array, name)
  94. {
  95.  local_var i, item;
  96.  if ( ! defined_func("replace_kb_item") || !_reuse_connection ) return 0;
  97.  for ( i = 0 ; i < max_index(array); i ++ )
  98.  {
  99.   replace_kb_item(name:name + "_" + i, value:string(array[i]));
  100.  }
  101. }
  102.  
  103. function load_array_from_kb(name)
  104. {
  105.  local_var array, n, item;
  106.  
  107.  if ( ! defined_func("get_kb_fresh_item") || !_reuse_connection ) return NULL;
  108.  n = 0;
  109.  array = make_list();
  110.  while ( TRUE )
  111.  {
  112.   item = get_kb_fresh_item(name + "_" + n );
  113.   if ( isnull(item) ) break;
  114.   array[n] = ssh_hex2raw(s:item);
  115.   n ++;
  116.  }
  117.  
  118.  return array;
  119. }
  120.  
  121. function load_intarray_from_kb(name)
  122. {
  123.  local_var array, n, item;
  124.  
  125.  if ( ! defined_func("get_kb_fresh_item") || !_reuse_connection ) return NULL;
  126.  n = 0;
  127.  array = make_list();
  128.  while ( TRUE )
  129.  {
  130.   item = get_kb_fresh_item(name + "_" + n );
  131.   if ( isnull(item) ) break;
  132.   array[n] = int(item);
  133.   n ++;
  134.  }
  135.  
  136.  return array;
  137. }
  138.  
  139. function kb_ssh_login()
  140. {
  141.  return string(get_kb_item("Secret/SSH/login"));
  142. }
  143.  
  144. function kb_ssh_password()
  145. {
  146.  return string(get_kb_item("Secret/SSH/password"));
  147. }
  148.  
  149. function kb_ssh_privatekey()
  150. {
  151.  return string(get_kb_item("Secret/SSH/privatekey"));
  152. }
  153.  
  154. function kb_ssh_publickey()
  155. {
  156.  return string(get_kb_item("Secret/SSH/publickey"));
  157. }
  158.  
  159. function kb_ssh_passphrase()
  160. {
  161.  return string(get_kb_item("Secret/SSH/passphrase"));
  162. }
  163.  
  164. function kb_ssh_transport()
  165. {
  166.  local_var r;
  167.  r = get_kb_item("Services/ssh");
  168.  
  169.  if ( r ) return int(r);
  170.  else return 22;
  171. }
  172.  
  173.  
  174. #-----------------------------------------------------------------#
  175. # Set SSH debugging error msg                                     #
  176. #-----------------------------------------------------------------#
  177. function set_ssh_error(msg)
  178. {
  179.  _ssh_error = msg;
  180. }
  181.  
  182.  
  183. #-----------------------------------------------------------------#
  184. # Get SSH debugging error msg                                     #
  185. #-----------------------------------------------------------------#
  186. function get_ssh_error()
  187. {
  188.  return _ssh_error;
  189. }
  190.  
  191.  
  192. #-----------------------------------------------------------------#
  193. # Get SSH server's version                                        #
  194. #-----------------------------------------------------------------#
  195. function get_ssh_supported_authentication()
  196. {
  197.  return _ssh_supported_authentication;
  198. }
  199.  
  200.  
  201. #-----------------------------------------------------------------#
  202. # Get SSH server's version                                        #
  203. #-----------------------------------------------------------------#
  204. function get_ssh_server_version()
  205. {
  206.  return _ssh_server_version;
  207. }
  208.  
  209.  
  210. #-----------------------------------------------------------------#
  211. # Get SSH banner                                                  #
  212. #-----------------------------------------------------------------#
  213. function get_ssh_banner()
  214. {
  215.  return _ssh_banner;
  216. }
  217.  
  218.  
  219. #-----------------------------------------------------------------#
  220. # Convert network long (buffer) to long                           #
  221. #-----------------------------------------------------------------#
  222. function ntol(buffer,begin)
  223. {
  224.  local_var len;
  225.  
  226.  len = 16777216*ord(buffer[begin]) +
  227.        ord(buffer[begin+1])*65536 +
  228.        ord(buffer[begin+2])*256 +
  229.        ord(buffer[begin+3]);
  230.  
  231.  return len;
  232. }
  233.  
  234. #-----------------------------------------------------------------#
  235. # Convert int to network long (raw_string)                        #
  236. #-----------------------------------------------------------------#
  237. function raw_int32(i)
  238. {
  239.  local_var buf;
  240.  
  241.  buf = raw_string (
  242.          (i>>24) & 255,
  243.         (i>>16) & 255,
  244.         (i>>8) & 255,
  245.         (i) & 255
  246.          );
  247.  return buf;
  248. }
  249.  
  250. #-----------------------------------------------------------------#
  251. # Convert char to network char (raw_string)                       #
  252. #-----------------------------------------------------------------#
  253. function raw_int8(i)
  254. {
  255.  local_var buf;
  256.  
  257.  buf = raw_string (
  258.         (i) & 255
  259.          );
  260.  return buf;
  261. }
  262.  
  263.  
  264. #-----------------------------------------------------------------#
  265. # Init packet sequence number and channel number                  #
  266. #-----------------------------------------------------------------#
  267. function init()
  268. {
  269.  # sequence packet = 0
  270.  seqn_w = seqn_r = 0;
  271.  local_channel = 0;
  272.  _ssh_banner = "";
  273.  _ssh_server_version = "";
  274.  _ssh_supported_authentication = "";
  275.  _ssh_cmd_error = "";
  276.  _ssh_error = "";
  277.  bugged_sshd = 0;
  278.  bugged_first = 1;
  279.  register_int_in_kb (int:bugged_sshd, name:"Secret/SSH/bugged_sshd");
  280.  #register_int_in_kb (int:bugged_first, name:"Secret/SSH/bugged_first");
  281.  
  282. }
  283.  
  284.  
  285. #-----------------------------------------------------------------#
  286. # Decode base64 string - ported from public domain code           #
  287. #-----------------------------------------------------------------#
  288. function base64decode(str)
  289. {
  290.  local_var len, i, j, k, ret, base64, b64;
  291.  len = strlen(str);
  292.  ret = "";
  293.  
  294.  base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  295.  
  296.  for (i = 0; i < 256; i++)
  297.    b64[i] = 0;
  298.  for (i = 0; i < strlen(base64); i++)
  299.    b64[ord(base64[i])] = i;
  300.  
  301.  for(j=0;j<len;j+=4)
  302.  {
  303.    for (i = 0; i < 4; i++)
  304.    {
  305.     c = ord(str[j+i]);
  306.     a[i] = c;
  307.     b[i] = b64[c];
  308.    }
  309.  
  310.    o[0] = (b[0] << 2) | (b[1] >> 4);
  311.    o[1] = (b[1] << 4) | (b[2] >> 2);
  312.    o[2] = (b[2] << 6) | b[3];
  313.    if (a[2] == ord('='))
  314.      i = 1;
  315.    else if (a[3] == ord('='))
  316.      i = 2;
  317.    else
  318.      i = 3;
  319.    for(k=0;k<i;k++)
  320.       ret += raw_int8(i:o[k]);
  321.    
  322.    if (i < 3) 
  323.      break;
  324.  }
  325.  
  326.  return ret;
  327. }
  328.  
  329.  
  330. #-----------------------------------------------------------------#
  331. # Reads a SSH packet (comes from smb_nt.inc)                      #
  332. #-----------------------------------------------------------------#
  333. function ssh_recv(socket, length)
  334. {
  335.   local_var header, len, trailer, cmpt, payload, ret;
  336.  
  337.   header = recv(socket:socket, length:4, min:4);
  338.   if (strlen(header) < 4)return(NULL);
  339.   len = ntol (buffer:header, begin:0);
  340.   if ((len == 0) || (len > 32768)) return(header);
  341.   trailer = recv(socket:socket, length:len, min:len);
  342.   if(strlen(trailer) < len )return(NULL);
  343.  
  344.   seqn_r++;
  345.   register_int_in_kb(name:"Secret/SSH/seqn_r", int:seqn_r);
  346.  
  347.   # SSH servers can send IGNORE (code 2) or BANNER (code 53) msg
  348.   ret = ord(trailer[1]);
  349.   if ((ret == 2) || (ret == 53))
  350.   {
  351.     if (ret == 53)
  352.       _ssh_banner += getstring (buffer:trailer, pos:2);
  353.  
  354.     return ssh_recv(socket:socket, length:length);
  355.   }
  356.  
  357.   return strcat(header, trailer);
  358. }
  359.  
  360.  
  361. #-----------------------------------------------------------------#
  362. # Detect if remote ssh server is known to be bugged (SunSSH1.0)   #
  363. #-----------------------------------------------------------------#
  364. function is_sshd_bugged(banner)
  365. {
  366.  if (ereg(string:banner, pattern:"^SSH-2\.0-Sun_SSH_1\.0"))
  367.    return 1;
  368.  
  369.  return 0;
  370. }
  371.  
  372.  
  373. #-----------------------------------------------------------------#
  374. # Waits for the server identification string, and sends our own   #
  375. # identification string.                                          #
  376. #-----------------------------------------------------------------#
  377. function ssh_exchange_identification(socket)
  378. {
  379.  local_var buf, sshversion, num, prot;
  380.  
  381.  buf = recv_line(socket:socket, length:1024);
  382.  
  383.  if (!buf)
  384.  {
  385.    set_ssh_error(msg: "Nessus did not receive server's version");
  386.    return 0;
  387.  }
  388.  
  389.  # server ident : SSH-%d.%d-servername #
  390.  if (!ereg(string:buf, pattern:"^SSH-*[0-9]\.*[0-9]-*[^\n]"))
  391.  {
  392.    set_ssh_error(msg: "Remote service is not a valid SSH service");
  393.    return 0;
  394.  }
  395.  
  396.  sshversion = split(buf, sep:"-", keep:0);
  397.  num = split(sshversion[1], sep:".", keep:0);
  398.  
  399.  # version supported = 2 & 1.99
  400.  if ((num[0] != 2) && !((num[0] == 1) && (num[1] == 99)))
  401.  {
  402.    set_ssh_error(msg: "Nessus only supports SSHv2");
  403.    return 0;
  404.  }
  405.  
  406.  # We use 2.0 protocol
  407.  prot = "SSH-2.0-Nessus"+raw_string(0x0a);
  408.  send(socket:socket, data:prot);
  409.  
  410.  if ( '\r\n' >< buf ) buf = buf - '\r\n';
  411.    else buf = buf - '\n';
  412.  
  413.  if (is_sshd_bugged(banner:buf))
  414.  {
  415.    bugged_sshd = 1;
  416.    register_int_in_kb (int:bugged_sshd, name:"Secret/SSH/bugged_sshd");
  417.  }
  418.  
  419.  # all is correct
  420.  return buf;
  421. }
  422.  
  423.  
  424. #-----------------------------------------------------------------#
  425. # check pattern in buffer                                         #
  426. # return next len in buffer or -1                                 #
  427. #-----------------------------------------------------------------#
  428. function check_pattern(buffer,pattern,length)
  429. {
  430.  local_var alglen, len, alg;
  431.  
  432.  alglen = ntol (buffer:buffer, begin:length);
  433.  len = length+4+alglen;
  434.  alg = substr(buffer,length+4,len-1);
  435.  if (!ereg(string:alg, pattern:pattern))
  436.   return -1;
  437.  
  438.  return len;
  439. }
  440.  
  441. #-----------------------------------------------------------------#
  442. # Create key exchange packet                                      #
  443. #-----------------------------------------------------------------#
  444. function kex_packet(payload,code)
  445. {
  446.  local_var len, padding_len, full_len, kex;
  447.  
  448.  len = 
  449.    # padding length
  450.      1 +
  451.      # msg code
  452.      1 +
  453.      # payload length
  454.      strlen(payload);
  455.   
  456.  #padding (mod 8) = 8 - ( (len+packet_len(4) ) % 8 ) 
  457.  padding_len = 8 - ((len + 4) % 8);
  458.  
  459.  # if padding len is less than 4 add block size
  460.  if (padding_len < 4)
  461.    padding_len += 8;
  462.  
  463.  full_len = len + padding_len;
  464.  
  465.  kex =
  466.     # packet length
  467.     raw_int32 (i:full_len) +
  468.     # padding length
  469.     raw_int8 (i:padding_len) +
  470.     #msg code (32 = Diffie-Hellman GEX Init)
  471.     code +
  472.     # Payload (Pub key)
  473.     payload +
  474.     # Padding
  475.     crap(data:raw_string(0),length:padding_len);
  476.  
  477.  return kex;
  478. }
  479.  
  480.  
  481. #-----------------------------------------------------------------#
  482. # mac compute                                                     #
  483. #-----------------------------------------------------------------#
  484. function mac_compute(data, type)
  485. {
  486.  local_var to_hash;
  487.  
  488.  # we only support sha1! enc_keys[5] == mac_out key
  489.  if (!type)
  490.  {
  491.   to_hash = raw_int32(i:seqn_w) + data;
  492.   hash = HMAC_SHA1(data:to_hash, key:enc_keys[4]);
  493.  }
  494.  else
  495.  {
  496.   to_hash = raw_int32(i:seqn_r) + data;
  497.   hash = HMAC_SHA1(data:to_hash, key:enc_keys[5]);
  498.  }
  499.  
  500.  return hash;
  501. }
  502.  
  503.  
  504. #-----------------------------------------------------------------#
  505. # crypt data                                                      #
  506. #-----------------------------------------------------------------#
  507. function crypt(data)
  508. {
  509.  local_var crypted;
  510.  
  511.  crypted = bf_cbc_encrypt(data:data, key:enc_keys[2], iv:enc_keys[0]);
  512.  
  513.  enc_keys[0] = crypted[1];
  514.  
  515.  register_array_in_kb(array:enc_keys, name:"Secret/SSH/enc_keys"); 
  516.  return crypted[0];
  517. }
  518.  
  519. #-----------------------------------------------------------------#
  520. # decrypt data                                                    #
  521. #-----------------------------------------------------------------#
  522. function decrypt(data)
  523. {
  524.  local_var decrypted;
  525.  
  526.  decrypted = bf_cbc_decrypt(data:data, key:enc_keys[3], iv:enc_keys[1]);
  527.  
  528.  enc_keys[1] = decrypted[1];
  529.  register_array_in_kb(array:enc_keys, name:"Secret/SSH/enc_keys"); 
  530.  return decrypted[0];
  531. }
  532.  
  533. #-----------------------------------------------------------------#
  534. # Send ssh packet                                                 #
  535. #-----------------------------------------------------------------#
  536. function send_ssh_packet(socket,payload,code)
  537. {
  538.  local_var i, len, padding_len, full_len, buf, res, macbuf, crypted;
  539.  
  540.  len = 
  541.    # padding length
  542.      1 +
  543.      # msg code
  544.      1 +
  545.      # payload length
  546.      strlen(payload);
  547.   
  548.  #padding (mod 8) = 8 - ( (len+packet_len(4) ) % 8 ) 
  549.  padding_len = 8 - ((len + 4) % 8);
  550.  
  551.  # if padding len is less than 4 add block size
  552.  if (padding_len < 4)
  553.    padding_len += 8;
  554.  
  555.  full_len = len + padding_len;
  556.  
  557.  padding = "";
  558.  for (i=0;i<padding_len;i++)
  559.     padding = padding + raw_int8(i:(rand() % 256)); 
  560.  
  561.  
  562.  buf =
  563.     # packet length
  564.     raw_int32 (i:full_len) +
  565.     # padding length
  566.     raw_int8 (i:padding_len) +
  567.     #msg code (32 = Diffie-Hellman GEX Init)
  568.     code +
  569.     # Payload (Pub key)
  570.     payload +
  571.     # Padding
  572.     padding;
  573.  
  574.  macbuf = mac_compute(data:buf, type:0);
  575.  
  576.  crypted = crypt(data:buf);
  577.  
  578.  buf = crypted + macbuf;
  579.  
  580.  send(socket:socket, data:buf);
  581.  
  582.  seqn_w++;
  583.  register_int_in_kb(name:"Secret/SSH/seqn_w", int:seqn_w);
  584. }
  585.  
  586.  
  587. #-----------------------------------------------------------------#
  588. # Receive ssh packet                                              #
  589. #-----------------------------------------------------------------#
  590. function recv_ssh_packet(socket, timeout)
  591. {
  592.  local_var len, need, padding_len, full_len, buf, res, macbuf, decrypted;
  593.  local_var hmac, hmacbuf, mac, payload, ret;
  594.  
  595.  
  596.  payload = raw_int8(i:0);
  597.  
  598.  # blockbytes = 8 for blowfish-cbc
  599.  buf = recv(socket:socket, length:8, min:8, timeout:timeout);
  600.  if (strlen(buf) != 8)
  601.    return payload;
  602.  
  603.  decrypted = decrypt(data:buf);
  604.  
  605.  len = ntol(buffer:decrypted, begin:0);
  606.  # Maximum packet size is 32768 bytes
  607.  if (len > 32768)
  608.    return payload;
  609.  # 8 = blocksize ... i know it is not generic and it will be hard to change all
  610.  need = 4 + len - 8;
  611.  buf = recv(socket:socket, length:need, min:need, timeout:timeout);
  612.  if (strlen(buf) != need)
  613.    return payload;
  614.  
  615.  decrypted = decrypted + decrypt(data:buf);
  616.  
  617.  # hmac-sha1 length = 20 ... same comment as before
  618.  mac = recv(socket:socket, length:20, min:20, timeout:timeout);
  619.  if (strlen(mac) != 20)
  620.    return payload;
  621.  
  622.  macbuf = mac_compute(data:decrypted, type:1);
  623.  
  624.  hmac = hexstr(mac);
  625.  hmacbuf = hexstr(macbuf);
  626.  if (hmac >!< hmacbuf)
  627.    return payload;
  628.  
  629.  payload = substr(decrypted, 5, strlen(decrypted)-ord(decrypted[4])-1);
  630.  seqn_r++;
  631.  register_int_in_kb(name:"Secret/SSH/seqn_r", int:seqn_r);
  632.  
  633.  # SSH servers can send IGNORE (code 2) or BANNER (code 53) msg
  634.  ret = ord(payload[0]);
  635.  if ((ret == 2) || (ret == 53) || ret == 4)
  636.  {
  637.    if (ret == 53)
  638.      _ssh_banner += getstring (buffer:payload, pos:1);
  639.  
  640.    return recv_ssh_packet(socket:socket, timeout:timeout);
  641.  }
  642.  
  643.  return payload;
  644. }
  645.  
  646.  
  647. #-----------------------------------------------------------------#
  648. # Get payload from packet                                         #
  649. #-----------------------------------------------------------------#
  650. function packet_payload(packet,code)
  651. {
  652.  local_var packetlen, paddinglen, msgcode;
  653.  
  654.  packetlen = ntol(buffer:packet, begin:0);
  655.  paddinglen = ord(packet[4]);
  656.  msgcode = ord(packet[5]);
  657.  
  658.  # Diffie-Hellman Key Exchange Reply
  659.  if (msgcode != code)
  660.   return 0;
  661.  
  662.  payload = substr(packet,6,packetlen-1);
  663.  return payload;
  664. }
  665.  
  666. #-----------------------------------------------------------------#
  667. # Get string (lenght,string)                                      #
  668. #-----------------------------------------------------------------#
  669. function getstring(buffer,pos)
  670. {
  671.  local_var buf_len, buf;
  672.  
  673.  buf_len = ntol (buffer:buffer,begin:pos);
  674.  buf = substr(buffer,pos+4,pos+4+buf_len-1);
  675.  
  676.  return buf;
  677. }
  678.  
  679. #-----------------------------------------------------------------#
  680. # Put string (string)                                             #
  681. #-----------------------------------------------------------------#
  682. function putstring(buffer)
  683. {
  684.  local_var buf;
  685.  
  686.  buf = raw_int32(i:strlen(buffer)) + buffer;
  687.  
  688.  return buf;
  689. }
  690.  
  691. #-----------------------------------------------------------------#
  692. # Put bignum (string)                                             #
  693. #-----------------------------------------------------------------#
  694. function putbignum(buffer)
  695. {
  696.  local_var len, buf;
  697.  
  698.  if (ord(buffer[0]) & 0x80)
  699.  {
  700.    len = strlen(buffer)+1;
  701.    buf = raw_int32(i:len) + raw_string(0x00) + buffer;
  702.  }
  703.  else   
  704.    buf = raw_int32(i:strlen(buffer)) + buffer;
  705.  
  706.  return buf;
  707. }
  708.  
  709. #-----------------------------------------------------------------#
  710. # RSA verify signature                                            #
  711. #-----------------------------------------------------------------#
  712. function ssh_rsa_verify(e, n, signature, data)
  713. {
  714.  local_var hash, id_sha1, sigtype, nlen,
  715.     next, tmp_sig, siglen, len, sig,
  716.     hdecoid, hshaoid, hhash, decrypted ;
  717.  
  718. #comes directly from OpenBSD
  719.  id_sha1 = raw_string(
  720.     0x30, 0x21, 
  721.     0x30, 0x09,
  722.     0x06, 0x05,
  723.     0x2b, 0x0e, 0x03, 0x02, 0x1a, 
  724.     0x05, 0x00,
  725.     0x04, 0x14 
  726.     );
  727.  
  728.  if (!n)
  729.    return 0;
  730.  
  731.  sigtype = getstring(buffer:signature, pos:0);
  732.  if (sigtype >!< "ssh-rsa")
  733.    return 0;
  734.  
  735.  nlen = strlen(n);
  736.  if (ord(n[0]) == 0)
  737.    nlen--;
  738.  
  739.  # check minimum n size
  740.  if ( (nlen*8) < 768 )
  741.    return 0;
  742.  
  743.  next = 4 + strlen(sigtype);
  744.  tmp_sig = getstring(buffer:signature,pos:next);
  745.  siglen = strlen(tmp_sig);
  746.  
  747.  # bad signature (should be less than n)
  748.  if (siglen > nlen)
  749.    return 0;
  750.  
  751.  # Add padding if needed
  752.  if (siglen < nlen)
  753.  { 
  754.    len = nlen - siglen;
  755.    sig = crap(data:raw_string(0x00), length:len) + tmp_sig;
  756.  }
  757.  else
  758.    sig = tmp_sig;
  759.  
  760.  hash = SHA1(data);
  761.  
  762.  if (strlen(hash) != 20)
  763.    return 0;
  764.  
  765.  # must call RSA_public_decrypt from openssl, so convert arg - see ssh-rsa.c
  766.  decrypted = rsa_public_decrypt(sig:sig,e:e,n:n);
  767.  if (!decrypted)
  768.    return 0;
  769.  
  770.  if (strlen(decrypted) != (strlen(id_sha1)+20))
  771.    return 0;
  772.  
  773.  hdecoid = hexstr(substr(decrypted,0,strlen(id_sha1)-1));
  774.  hshaoid = hexstr(id_sha1);
  775.  
  776.  if (hdecoid >!< hshaoid)
  777.    return 0; 
  778.  
  779.  hdecoid = hexstr(substr(decrypted,strlen(id_sha1),strlen(decrypted)-1));
  780.  hhash = hexstr(hash);
  781.  
  782.  if (hdecoid >!< hhash)
  783.    return 0; 
  784.  
  785.  return 1;
  786. }
  787.  
  788.  
  789. #-----------------------------------------------------------------#
  790. # DSA verify signature                                            #
  791. #-----------------------------------------------------------------#
  792. function ssh_dss_verify(p, q, g, pub, signature, data)
  793. {
  794.  local_var sigtype, next, tmp_sig, siglen, r, s, hash;
  795.  
  796.  sigtype = getstring(buffer:signature, pos:0);
  797.  if (sigtype >!< "ssh-dss")
  798.    return 0;
  799.  
  800.  next = 4 + strlen(sigtype);
  801.  tmp_sig = getstring(buffer:signature,pos:next);
  802.  siglen = strlen(tmp_sig);
  803.  
  804.  r = substr(tmp_sig, 20, 39);
  805.  s = substr(tmp_sig, 40, 59);
  806.  
  807.  hash = SHA1(data);
  808.  
  809.  return dsa_do_verify(p:p,g:g,q:q,pub:pub,r:r,s:s,data:hash);
  810. }
  811.  
  812.  
  813. #-----------------------------------------------------------------#
  814. # Derive keys  (this function works because we only use sha1 and  #
  815. # blowfish so keylen is 20 due to sha1)                           #
  816. #-----------------------------------------------------------------#
  817. function derive_keys(hash,shared,session_id)
  818. {
  819.  local_var c, i, to_hash, keys;
  820.  # c = 'A';
  821.  c = 65;
  822.  for (i = 0;i < 6; i++)
  823.  {
  824.    to_hash = putbignum(buffer:shared) + hash + raw_int8(i:c) + session_id;
  825.    keys[i] = SHA1(to_hash);
  826.    c++;
  827.  }
  828.  
  829.  #         MODE OUT  MODE IN
  830.  # enc.iv    0         1
  831.  # enc.key   2         3
  832.  # mac.key   4         5
  833.  
  834.  return keys;
  835. }
  836.  
  837.  
  838. #-----------------------------------------------------------------#
  839. # Check is public key is correct                                  #
  840. #-----------------------------------------------------------------#
  841. function dh_valid_key(key, p)
  842. {
  843.  local_var val,i;
  844.  
  845.  if (ord(key[0]) > 0x80)
  846.    return 0;
  847.  
  848.  val = 0;
  849.  for(i=0;i<strlen(key);i++)
  850.  {
  851.   val = val + ord(key[i]);
  852.   if (val > 1)
  853.     break;
  854.  }
  855.  
  856.  # ok if key < p
  857.  if ((val>1) && (bn_cmp(key1:key,key2:p) == -1))
  858.    return 1;
  859.  
  860.  return 0;
  861. }
  862.  
  863.  
  864. #-----------------------------------------------------------------#
  865. # Genereate dh public & private keys                              #
  866. #-----------------------------------------------------------------#
  867. function dh_gen_key(p, g)
  868. {
  869.  local_var tries,keys;
  870.  
  871.  dh_pub = dh_priv = "";
  872.  
  873.  tries = 0;
  874.  
  875.  if (!p)
  876.    return keys;
  877.  
  878.  # { "blowfish-cbc",     SSH_CIPHER_SSH2, 8, 16, EVP_bf_cbc }
  879.  # hash = sha1 = 20 (len) = 20 * 8 (bits)
  880.  need = 20 * 8;
  881.  
  882.  # need won't be > than INT_MAX / 2
  883.  # maybe we must test if 2*need >= numbits ...
  884.  #if (need > INT_MAX / 2 || 2 * need >= BN_num_bits(dh->p))
  885.  #  return keys;
  886.  
  887.  for (tries = 0; tries < 10; tries++)
  888.  {
  889.    dh_priv = bn_random(need:(need*2));
  890.    if (!dh_priv)
  891.      return -1;
  892.    dh_pub = dh_generate_key(p:p, g:g, priv:dh_priv);
  893.    if (!dh_pub)
  894.      return -1;
  895.    if (dh_valid_key(key:dh_pub, p:p))
  896.      break;
  897.  }
  898.  
  899.  if (tries++ >= 10)
  900.    return -1;
  901.  
  902.  return 0;
  903. }
  904.  
  905.  
  906. #-----------------------------------------------------------------#
  907. # Waits for the server identification string, and sends our own   #
  908. # identification string.                                          #
  909. #-----------------------------------------------------------------#
  910. function ssh_kex2(socket,server_version)
  911. {
  912.  local_var packetlen, paddinglen, msgcode, len, len2;
  913.  local_var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p;
  914.  local_var skexkex, kexr, skexr, gex, gexr, nk, nkey;
  915.  local_var sinit, scookie, ccookie, cinit;
  916.  local_var payload; 
  917.  local_var keys, server_host_key_blob, shared; 
  918.  local_var alg_type, type;
  919.  local_var start, next, correct, groupex; 
  920.  local_var rsa_e, rsa_n, dsa_p, dsa_q, dsa_g, dsa_pub_key; 
  921.  local_var server_dh_public_key, signed_h, to_hash, hash;
  922.     
  923.  
  924.  # supported algorithms
  925.  key_exchange_algo        = "diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1";
  926.  server_host_key_algo     = "ssh-rsa,ssh-dss";
  927.  enc_alg_client_to_server = "blowfish-cbc";
  928.  enc_alg_server_to_client = "blowfish-cbc";
  929.  mac_alg_client_to_server = "hmac-sha1";
  930.  mac_alg_server_to_client = "hmac-sha1";
  931.  cmp_alg_client_to_server = "none";
  932.  cmp_alg_server_to_client = "none";
  933.  
  934.  # version
  935.  client_version = "SSH-2.0-Nessus";
  936.  
  937.  
  938. ### Key exchange send client Init ###
  939.  
  940.  skex = ssh_recv(socket:socket, length:2000);
  941.  packetlen = ntol (buffer:skex, begin:0);
  942.  paddinglen = ord(skex[4]);
  943.  msgcode = ord(skex[5]);
  944.  if (msgcode != 20)
  945.  {
  946.    set_ssh_error(msg:string("Received code was not SSH_MSG_KEXINIT (20). It was : ", msgcode));
  947.    return -1;
  948.  }
  949.  
  950.  sinit = substr(skex,6,packetlen+4-paddinglen-1);
  951.  
  952.  scookie = substr(skex,6,21);
  953.  
  954.  len = check_pattern(buffer:skex, pattern:"diffie-hellman-group-exchange-sha1", length:22);
  955.  if (len == -1)
  956.  {
  957.    len = check_pattern(buffer:skex, pattern:"diffie-hellman-group1-sha1", length:22);
  958.    if (len == -1)
  959.    {
  960.      set_ssh_error(msg:"Remote SSH server does not support DH exchanges (bugged ?)");
  961.      return -1;
  962.    }
  963.    groupex = 0;
  964.  }
  965.  else
  966.  {
  967.   groupex = 1;
  968.  }
  969.  
  970.  len2 = check_pattern(buffer:skex, pattern:"ssh-rsa", length:len);
  971.  if (len2 == -1)
  972.  {
  973.    len2 = check_pattern(buffer:skex, pattern:"ssh-dss", length:len);
  974.    if (len2 == -1)
  975.    {
  976.      set_ssh_error(msg:"Remote SSH server does not support DSA and RSA (bugged ?)");
  977.      return -1;
  978.    }
  979.  }
  980.  
  981.  len = check_pattern(buffer:skex, pattern:enc_alg_client_to_server, length:len2);
  982.  if (len == -1)
  983.  {
  984.   set_ssh_error(msg:"Remote SSH server does not support blowfish-cbc encryption");
  985.   return -1;
  986.  }
  987.  
  988.  len2 = check_pattern(buffer:skex, pattern:enc_alg_server_to_client, length:len);
  989.  if (len2 == -1)
  990.  {
  991.   set_ssh_error(msg:"Remote SSH server does not support blowfish-cbc encryption");
  992.   return -1;
  993.  }
  994.  
  995.  len = check_pattern(buffer:skex, pattern:mac_alg_client_to_server, length:len2);
  996.  if (len == -1)
  997.  {
  998.   set_ssh_error(msg:"Remote SSH server does not support hmac-sha1 encryption");
  999.   return -1;
  1000.  }
  1001.  
  1002.  len2 = check_pattern(buffer:skex, pattern:mac_alg_server_to_client, length:len);
  1003.  if (len2 == -1)
  1004.  {
  1005.   set_ssh_error(msg:"Remote SSH server does not support hmac-sha1 encryption");
  1006.   return -1;
  1007.  }
  1008.  
  1009.  len = check_pattern(buffer:skex, pattern:cmp_alg_client_to_server, length:len2);
  1010.  if (len == -1)
  1011.  {
  1012.   set_ssh_error(msg:"Remote SSH server only supports compressed packets");
  1013.   return -1;
  1014.  }
  1015.  
  1016.  len2 = check_pattern(buffer:skex, pattern:cmp_alg_server_to_client, length:len);
  1017.  if (len2 == -1)
  1018.  {
  1019.   set_ssh_error(msg:"Remote SSH server only supports compressed packets");
  1020.   return -1;
  1021.  }
  1022.  
  1023.  
  1024. ### Key exchange recv server Init ###
  1025.  
  1026.  ccookie = "";
  1027.  for (i=0;i<16;i++)
  1028.     ccookie = ccookie + raw_int8(i:(rand() % 256)); 
  1029.  
  1030.  cinit =
  1031.     # cookie (random)
  1032.     ccookie +
  1033.     # key algorithms (length + string)
  1034.     raw_int32(i:strlen(key_exchange_algo)) + key_exchange_algo +
  1035.     # server host key algorithms (length + string)
  1036.     raw_int32(i:strlen(server_host_key_algo)) + server_host_key_algo +
  1037.     # encryption algorithms client to server (length + string)
  1038.     raw_int32(i:strlen(enc_alg_client_to_server)) + enc_alg_client_to_server +
  1039.     # encryption algorithms server to client (length + string)
  1040.     raw_int32(i:strlen(enc_alg_server_to_client)) + enc_alg_server_to_client +
  1041.     # mac algorithms client to server (length + string)
  1042.     raw_int32(i:strlen(mac_alg_client_to_server)) + mac_alg_client_to_server +
  1043.     # mac algorithms server to client (length + string)
  1044.     raw_int32(i:strlen(mac_alg_server_to_client)) + mac_alg_server_to_client +
  1045.     # compression algorithms client to server (length + string)
  1046.     raw_int32(i:strlen(cmp_alg_client_to_server)) + cmp_alg_client_to_server +
  1047.     # compression algorithms server to client (length + string)
  1048.     raw_int32(i:strlen(cmp_alg_server_to_client)) + cmp_alg_server_to_client +
  1049.     # languages client to server (lenght)
  1050.     raw_int32(i:0) +
  1051.     # languages server to client (lenght)
  1052.     raw_int32(i:0) +
  1053.     # payload
  1054.     crap(data:raw_string(0x00), length:5);
  1055.  
  1056.  # msg code (20 = key exchange init)
  1057.  kex = kex_packet(payload:cinit,code:raw_string(0X14));
  1058.  
  1059.  send(socket:socket, data:kex);
  1060.  seqn_w++;
  1061.  register_int_in_kb(name:"Secret/SSH/seqn_w", int:seqn_w);
  1062.  
  1063.  
  1064.  if (groupex)
  1065.  {
  1066.   ### Key exchange Request : Diffie-Hellman GEX Request ###
  1067.  
  1068.   payload = raw_string(0x00,0x00,0x04,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x20,0x00);
  1069.   # msg code (34 = Diffie-Hellman GEX Request)
  1070.   kexr = kex_packet(payload:payload,code:raw_string(34));
  1071.  
  1072.   send(socket:socket, data:kexr);
  1073.   seqn_w++;
  1074.  register_int_in_kb(name:"Secret/SSH/seqn_w", int:seqn_w);
  1075.  
  1076.  
  1077.   ### Key exchange Reply : Diffie-Hellman Key Exchange Reply ###
  1078.  
  1079.   skexr = ssh_recv(socket:socket, length:1000);
  1080.  
  1081.   # code = 31 (Diffie-Hellman Key Exchange Reply)
  1082.   payload = packet_payload(packet:skexr, code:31);
  1083.   if (!payload)
  1084.   {
  1085.    set_ssh_error(msg:"Received code was not SSH_MSG_KEXDH_REPLY (31)");
  1086.    return -1;
  1087.   }
  1088.  
  1089.   # get p bignum for dh group
  1090.   p = getstring (buffer:payload,pos:0);
  1091.  
  1092.   # get g bignum for dh group
  1093.   start = 4+strlen(p);
  1094.   g = getstring(buffer:payload,pos:start);
  1095.  }
  1096.  else
  1097.  {
  1098.   p = raw_string (0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  1099.                   0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
  1100.                   0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
  1101.                   0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
  1102.                   0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
  1103.                   0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
  1104.                   0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
  1105.                   0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
  1106.                   0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
  1107.                   0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
  1108.                   0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
  1109.                   0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
  1110.                   0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
  1111.                   0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
  1112.                   0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81,
  1113.                   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
  1114.  
  1115.   g = raw_int8(i:2);
  1116.  }
  1117.  # generate public and private keys
  1118.  ret = dh_gen_key(p:p,g:g);
  1119.  if (ret != 0)
  1120.   {
  1121.    set_ssh_error(msg:"Error during DH keys generation");
  1122.    return -1;
  1123.   }
  1124.  
  1125.  register_data_in_kb(name:"Secret/SSH/dh_pub", data:dh_pub);
  1126.  register_data_in_kb(name:"Secret/SSH/dh_priv", data:dh_priv);
  1127.  
  1128. ### Diffie Hellman GEX Init ###
  1129.  
  1130.  payload = raw_int32(i:strlen(dh_pub)) + dh_pub;
  1131.  
  1132.  if (groupex)
  1133.    codereq = raw_int8(i:32);
  1134.  else
  1135.    codereq = raw_int8(i:30);
  1136.  
  1137.  # msg code (32 = Diffie-Hellman GEX Init)
  1138.  gex = kex_packet(payload:payload,code:codereq);
  1139.  
  1140.  send(socket:socket, data:gex);
  1141.  seqn_w++;
  1142.  register_int_in_kb(name:"Secret/SSH/seqn_w", int:seqn_w);
  1143.  
  1144. ### Diffie Hellman GEX Reply ###
  1145.  
  1146.  gexr = ssh_recv(socket:socket, length:2000);
  1147.  
  1148.  if (groupex)
  1149.    codereq = 33;
  1150.  else
  1151.    codereq = 31;
  1152.  payload = packet_payload(packet:gexr, code:codereq);
  1153.  if (!payload)
  1154.  {
  1155.   set_ssh_error(msg:"Received code was not SSH_MSG_KEXDH_REPLY (31 or 33)");
  1156.   return -1;
  1157.  }
  1158.  
  1159.  # server host key blob
  1160.  server_host_key_blob = getstring (buffer:payload,pos:0);
  1161.  
  1162.  # extract server host key
  1163.  alg_type = getstring (buffer:server_host_key_blob, pos:0);
  1164.  next = 4 + strlen(alg_type);
  1165.  
  1166.  if (alg_type >< "ssh-rsa")
  1167.   {
  1168.    # rsa type == 0
  1169.    type = 0; 
  1170.  
  1171.    # e
  1172.    rsa_e = getstring (buffer:server_host_key_blob,pos:next);
  1173.    next = next + 4 + strlen(rsa_e);
  1174.  
  1175.    # n
  1176.    rsa_n = getstring (buffer:server_host_key_blob,pos:next);
  1177.    next = next + 4 + strlen(rsa_n);
  1178.   }
  1179.  else
  1180.   {
  1181.    if (alg_type >< "ssh-dss")
  1182.     {
  1183.      # dsa type == 1
  1184.      type = 1; 
  1185.  
  1186.      # p
  1187.      dsa_p = getstring (buffer:server_host_key_blob,pos:next);
  1188.      next = next + 4 + strlen(dsa_p);
  1189.  
  1190.      # q
  1191.      dsa_q = getstring (buffer:server_host_key_blob,pos:next);
  1192.      next = next + 4 + strlen(dsa_q);
  1193.  
  1194.      # g
  1195.      dsa_g = getstring (buffer:server_host_key_blob,pos:next);
  1196.      next = next + 4 + strlen(dsa_g);
  1197.  
  1198.      # pub key
  1199.      dsa_pub_key = getstring (buffer:server_host_key_blob,pos:next);
  1200.      next = next + 4 + strlen(dsa_pub_key);
  1201.     }
  1202.    else
  1203.     # bad key algo - should not occur
  1204.    {
  1205.      set_ssh_error(msg:"Server's host keys format is not supported");
  1206.      return -1;
  1207.    }
  1208.   }  
  1209.  
  1210.  
  1211.  # server dh public key
  1212.  start = 4 + strlen(server_host_key_blob);
  1213.  server_dh_public_key = getstring(buffer:payload,pos:start);
  1214.  
  1215.  # signed H
  1216.  start = start + 4 + strlen(server_dh_public_key);
  1217.  signed_h = getstring(buffer:payload,pos:start);
  1218.   
  1219.  if (!dh_valid_key(key:server_dh_public_key, p:p))
  1220.  {
  1221.    set_ssh_error(msg:"Server DH public key is not valid!");
  1222.    return -1;
  1223.  }
  1224.  
  1225.  # shared secret #
  1226.  shared = dh_compute_key(p:p,g:g,dh_server_pub:server_dh_public_key,
  1227.   pub_key:dh_pub,priv_key:dh_priv);
  1228.  if (!shared)
  1229.  {
  1230.    set_ssh_error(msg:"Error during shared secret computing");
  1231.    return -1;
  1232.  }
  1233.  
  1234.  # hash data
  1235.  to_hash = 
  1236.     # client version
  1237.     putstring(buffer:client_version) +
  1238.     # server version
  1239.     putstring(buffer:server_version) +
  1240.     # client cookie (cookielen,SSH_MSG_KEXINIT,cookie)
  1241.     raw_int32(i:(strlen(cinit)+1)) + raw_int8(i:20) + cinit +
  1242.     # server cookie (cookielen,SSH_MSG_KEXINIT,cookie)
  1243.     raw_int32(i:(strlen(sinit)+1)) + raw_int8(i:20) + sinit +
  1244.     # server host key blob
  1245.     putstring(buffer:server_host_key_blob);
  1246.  
  1247.  if (groupex)
  1248.  {
  1249.   to_hash += 
  1250.     # min,wantbits,max
  1251.     raw_string(0x00,0x00,0x04,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x20,0x00) +
  1252.     # p bignum
  1253.     putbignum(buffer:p) +
  1254.     # g bignum
  1255.     putbignum(buffer:g);
  1256.  }
  1257.  
  1258.  to_hash +=
  1259.     # public key bignum
  1260.     putbignum(buffer:dh_pub) +
  1261.     # server dh public key bignum
  1262.     putbignum(buffer:server_dh_public_key) +
  1263.     # shared bignum
  1264.     putbignum(buffer:shared);
  1265.  
  1266.  hash = SHA1(to_hash); 
  1267.  
  1268.  if (type == 0)
  1269.    correct = ssh_rsa_verify(e:rsa_e, n:rsa_n, signature:signed_h, data:hash);
  1270.  else
  1271.    # Not implemented
  1272.    correct = ssh_dss_verify(p:dsa_p, q:dsa_q, g:dsa_g, pub:dsa_pub_key, signature:signed_h, data:hash);
  1273.  
  1274.  if (!correct)
  1275.  {
  1276.    set_ssh_error(msg:"Server's signature is not valid!");
  1277.    return -1;
  1278.  }
  1279.  
  1280.  session_id = hash;
  1281.  register_data_in_kb(name:"Secret/SSH/session_id", data:session_id);
  1282.  enc_keys = derive_keys(hash:hash,shared:shared,session_id:session_id);
  1283.  register_array_in_kb(array:enc_keys, name:"Secret/SSH/enc_keys");
  1284.  
  1285. ### New keys ###
  1286.  
  1287.  nkey = ssh_recv(socket:socket, length:1000);
  1288.  # msg code (21 = New keys)
  1289.  payload = packet_payload(packet:nkey, code:21);
  1290.  if (!payload)
  1291.  {
  1292.   set_ssh_error(msg:"Received code was not SSH_MSG_NEWKEYS (21)");
  1293.   return -1;
  1294.  }
  1295.  
  1296.  payload = NULL;
  1297.  
  1298.  # msg code (21 = New keys)
  1299.  nk = kex_packet(payload:payload,code:raw_string(0x15));
  1300.  
  1301.  send(socket:socket, data:nk);
  1302.  seqn_w++;
  1303.  register_int_in_kb(name:"Secret/SSH/seqn_w", int:seqn_w);
  1304.  
  1305.  # all is correct
  1306.  return 0; 
  1307. }
  1308.  
  1309.  
  1310. #-----------------------------------------------------------------#
  1311. # Authenticate to SSH server                                      #
  1312. #-----------------------------------------------------------------#
  1313. function ssh_userauth2(socket, server_user, password, pub, priv, passphrase)
  1314. {
  1315.  local_var payload, buf, support, pass, pkey, kb, authenticated, blobpub, signature, blobpriv, privkey, typestr, next, e, n, hash2, hash, public, line, num, pubtab, i, crap, kb_ok;
  1316.  
  1317.  pass = pkey = authenticated = kb = 0;
  1318.  
  1319.  payload = putstring(buffer:"ssh-userauth");
  1320.  
  1321.  # code 5 (SSH_MSG_SERVICE_REQUEST)
  1322.  send_ssh_packet(socket:socket, payload:payload, code:raw_string(0x05));
  1323.  
  1324.  # code 6 (SSH_MSG_SERVICE_ACCEPT)
  1325.  payload = recv_ssh_packet(socket:socket);
  1326.  if (ord(payload[0]) != 6)
  1327.  {
  1328.    set_ssh_error(msg:string("Server does not support ssh-userauth service. Received code was : " , ord(payload[0])));
  1329.    return -1;
  1330.  }
  1331.  
  1332.  # service accepted
  1333.  # code 50 (SSH_MSG_USERAUTH_REQUEST)
  1334.  # none request: we need to know what authentification server supports
  1335.  payload = putstring(buffer:server_user) + putstring(buffer:"ssh-connection") +
  1336.     putstring(buffer:"none");
  1337.  send_ssh_packet(socket:socket, payload:payload, code:raw_int8(i:50));
  1338.  
  1339.  # (51 == SSH_MSG_USERAUTH_FAILURE)
  1340.  payload = recv_ssh_packet(socket:socket);
  1341.  if (ord(payload[0]) != 51)
  1342.  {
  1343.    set_ssh_error(msg:string("Server did not reject none authentication method. Received code was : " , ord(payload[0])));
  1344.    return -1;
  1345.  }
  1346.  
  1347.  support = getstring(buffer:payload,pos:1);
  1348.  
  1349.  _ssh_supported_authentication = support;
  1350.  
  1351.  if (pub && priv)
  1352.  {
  1353.    if (ereg(string:support, pattern:"publickey"))
  1354.      pkey = 1;
  1355.    else
  1356.    {
  1357.      set_ssh_error(msg:string("Error : Remote server does not support publickey authentication method! It supports : " , support));
  1358.      return -1;   
  1359.    }
  1360.  }
  1361.  else if (password)
  1362.  {
  1363.    if (ereg(string:support, pattern:"password"))
  1364.      pass = 1;
  1365.    else if (ereg(string:support, pattern:"keyboard-interactive"))
  1366.      kb = 1;
  1367.    else
  1368.    {
  1369.      set_ssh_error(msg:string("Error : Remote server does not support one of the following password authentication methods : password, keyboard-interactive. It supports : " , support));
  1370.      return -1;   
  1371.    }
  1372.  }
  1373.  else
  1374.  {
  1375.    set_ssh_error(msg:"Nessus needs public and private keys or a password!");
  1376.    return -1;
  1377.  }
  1378.  
  1379.  
  1380.  if (pass)
  1381.  {
  1382.   # code 50 (SSH_MSG_USERAUTH_REQUEST)
  1383.   ###### need extra pad !!!! ######
  1384.   ###### Is it usefull ?? #####
  1385.   payload = putstring(buffer:server_user) + putstring(buffer:"ssh-connection") +
  1386.     putstring(buffer:"password") + raw_int8(i:0) + putstring(buffer:password)
  1387.     ;
  1388.  
  1389.   send_ssh_packet(socket:socket, payload:payload, code:raw_int8(i:50));
  1390.  
  1391.   # code 52 (SSH_MSG_USERAUTH_SUCCESS)
  1392.   payload = recv_ssh_packet(socket:socket);
  1393.   if (ord(payload[0]) == 52)
  1394.      authenticated = 1;
  1395.  
  1396.   if (!authenticated)
  1397.   {
  1398.     set_ssh_error(msg:"Password authentication failed");
  1399.     return -1;
  1400.   }
  1401.  }
  1402.  else if (kb)
  1403.  {
  1404.   # code 50 (SSH_MSG_USERAUTH_REQUEST)
  1405.   payload = putstring(buffer:server_user) + putstring(buffer:"ssh-connection") +
  1406.     putstring(buffer:"keyboard-interactive") + putstring(buffer:"en-US") + putstring(buffer:"")
  1407.     ;
  1408.  
  1409.   send_ssh_packet(socket:socket, payload:payload, code:raw_int8(i:50));
  1410.  
  1411.   # code 60 (SSH_MSG_USERAUTH_INFO_REQUEST)
  1412.   payload = recv_ssh_packet(socket:socket);
  1413.   if (ord(payload[0]) != 60)
  1414.   {
  1415.     set_ssh_error(msg:string("Server did not reply with SSH_MSG_USERAUTH_INFO_REQUEST during keyboard-interactive exchange. It replied with :", ord(payload[0])));
  1416.     return -1;
  1417.   }
  1418.  
  1419.   # Method name
  1420.   crap = getstring (buffer:payload,pos:1);
  1421.   next = 1 + 4 + strlen(crap);
  1422.  
  1423.   # Method name complement
  1424.   crap = getstring (buffer:payload,pos:next);
  1425.   next = next + 4 + strlen(crap);
  1426.  
  1427.   # Language
  1428.   crap = getstring (buffer:payload,pos:next);
  1429.   next = next + 4 + strlen(crap);
  1430.   
  1431.   # Number of request
  1432.   num = ntol(buffer:payload, begin:next);
  1433.   next += 4;
  1434.  
  1435.   kb_ok = 0;
  1436.   if (num > 0)
  1437.   {
  1438.     crap = getstring (buffer:payload,pos:next);
  1439.     if ("Password: " >< crap)
  1440.       kb_ok = 1;
  1441.   }
  1442.  
  1443.   if (!kb_ok)
  1444.   {
  1445.     set_ssh_error(msg:"Remote server keyboard-interactive method does not support Password.");
  1446.     return -1;   
  1447.   }
  1448.  
  1449.   # code 61 (SSH_MSG_USERAUTH_INFO_RESPONSE)
  1450.   payload = raw_int32(i:1) + putstring(buffer:password);
  1451.  
  1452.   send_ssh_packet(socket:socket, payload:payload, code:raw_int8(i:61));
  1453.  
  1454.   payload = recv_ssh_packet(socket:socket);
  1455.   
  1456.   # From draft-ietf-secsh-auth-kbdinteract-06.txt document :
  1457.   # Server should now send SSH_MSG_USERAUTH_INFO_REQUEST.
  1458.   # REQUEST can ask additionnal informations (like a new password).
  1459.   # But if all is correct num-prompts is set to 0 and client must
  1460.   # reply with an empty SSH_MSG_USERAUTH_INFO_RESPONSE.
  1461.   # So we just send an empty response and look if authentication
  1462.   # works. If remote server asked for additionnal informations,
  1463.   # authentication will just failed.
  1464.   if (ord(payload[0]) == 60)
  1465.   {
  1466.    # code 61 (SSH_MSG_USERAUTH_INFO_RESPONSE)
  1467.    payload = raw_int32(i:0);
  1468.    send_ssh_packet(socket:socket, payload:payload, code:raw_int8(i:61));
  1469.    payload = recv_ssh_packet(socket:socket);
  1470.   }
  1471.   if (ord(payload[0]) != 52)
  1472.   {
  1473.     set_ssh_error(msg:string("Server did not reply with SSH_MSG_USERAUTH_SUCCESS during keyboard-interactive exchange. It replied with :",ord(payload[0])));
  1474.     return -1;
  1475.   }
  1476.   
  1477.   authenticated = 1;
  1478.  }
  1479.  
  1480.  else if (!authenticated && pkey)
  1481.  {
  1482.   # SSH Public Key File Format (draft-ietf-secsh-publickeyfile-05.txt)
  1483.   # ---- BEGIN SSH2 PUBLIC KEY ----
  1484.   # Comment: "1024-bit RSA, converted from OpenSSH by galb@test1"
  1485.   # AAAAB3NzaC1yc2EAAAABIwAAAIEA1on8gxCGJJWSRT4uOrR13mUaUk0hRf4RzxSZ1zRbYY
  1486.   # Fw8pfGesIFoEuVth4HKyF8k1y4mRUnYHP1XNMNMJl1JcEArC2asV8sHf6zSPVffozZ5TT4
  1487.   # SfsUu/iKy9lUcCfXzwre4WWZSXXcPff+EHtWshahu3WzBdnGxm5Xoi89zcE=
  1488.   # ---- END SSH2 PUBLIC KEY ----
  1489.   if ("---" >< pub)
  1490.   {
  1491.     public = "";
  1492.     pubtab = split(pub, sep:'\n', keep:0);
  1493.     num = max_index(pubtab);
  1494.     for (i=0; i<num; i++)
  1495.     {
  1496.       line = pubtab[i];
  1497.       if (("---" >!< line) && (":" >!< line))
  1498.       {
  1499.         if ('\r' >< line)
  1500.           line -= '\r';
  1501.         public += line;
  1502.       }
  1503.     }      
  1504.   }
  1505.   else
  1506.   {
  1507.     # OpenSSH Public key file format
  1508.     public = ereg_replace(pattern:"[^ ]* ([^ ]*) [^ ]*$",
  1509.                       string:pub,
  1510.                   replace:"\1");
  1511.   }
  1512.  
  1513.   blobpub = base64decode(str:public);
  1514.  
  1515.   # code 50 (SSH_MSG_USERAUTH_REQUEST)
  1516.   ###### need extra pad !!!! ######
  1517.   ###### Is it usefull ?? #####
  1518.  
  1519.   payload = putstring(buffer:server_user) + putstring(buffer:"ssh-connection") +
  1520.     putstring(buffer:"publickey") + raw_int8(i:1) ; 
  1521.  
  1522.   to_hash = putstring(buffer:session_id) + raw_int8(i:50);
  1523.  
  1524.   typestr = getstring(buffer:blobpub, pos:0);
  1525.   if ("ssh-rsa" >< typestr)
  1526.   {
  1527.     next = 4 + strlen(typestr);
  1528.     e = getstring(buffer:blobpub, pos:next);
  1529.     next = next + 4 + strlen(e);
  1530.     n = getstring(buffer:blobpub, pos:next);
  1531.  
  1532.     privkey = pem_to_rsa(priv:priv, passphrase:passphrase);
  1533.     if (!privkey)
  1534.      {
  1535.       set_ssh_error(msg:"Nessus failed to load SSH private key (RSA)");
  1536.       return -1;
  1537.      }
  1538.  
  1539.     payload += putstring(buffer:"ssh-rsa") + putstring(buffer:blobpub);
  1540.  
  1541.     to_hash += payload;
  1542.  
  1543.     hash = SHA1(to_hash);
  1544.     signature = rsa_sign(e:e, n:n, d:privkey, data:hash);
  1545.     if (!signature)
  1546.     {
  1547.       set_ssh_error(msg:"Error during client's RSA signature computing");
  1548.       return -1;
  1549.     }
  1550.  
  1551.     signature = putstring(buffer:"ssh-rsa") + putstring(buffer:signature);
  1552.   }
  1553.   else if ("ssh-dss" >< typestr)
  1554.   {
  1555.     # p
  1556.     next = 4 + strlen(typestr);
  1557.     p = getstring (buffer:blobpub,pos:next);
  1558.     next = next + 4 + strlen(p);
  1559.  
  1560.     # q
  1561.     q = getstring (buffer:blobpub,pos:next);
  1562.     next = next + 4 + strlen(q);
  1563.  
  1564.     # g
  1565.     g = getstring (buffer:blobpub,pos:next);
  1566.     next = next + 4 + strlen(g);
  1567.  
  1568.     # pub key
  1569.     pub_key = getstring (buffer:blobpub,pos:next);
  1570.  
  1571.     privkey = pem_to_dsa(priv:priv, passphrase:passphrase);
  1572.     if (!privkey)
  1573.     {
  1574.       set_ssh_error(msg:"Nessus failed to load SSH private key (DSA)");
  1575.       return -1;
  1576.     }
  1577.  
  1578.     payload += putstring(buffer:"ssh-dss") + putstring(buffer:blobpub);
  1579.  
  1580.     to_hash += payload;
  1581.  
  1582.     hash = SHA1(to_hash);
  1583.     signature = dsa_do_sign(p:p, q:q, g:g, pub:pub_key, priv:privkey, data:hash);
  1584.     if (!signature)
  1585.      {
  1586.       set_ssh_error(msg:"Error during client's DSA signature computing");
  1587.       return -1;
  1588.      }
  1589.  
  1590.     signature = putstring(buffer:"ssh-dss") + putstring(buffer:signature);
  1591.  
  1592.   }
  1593.   else
  1594.   {
  1595.     set_ssh_error(msg:"Client's private key type is not supported");
  1596.     return -1;
  1597.   }
  1598.  
  1599.   payload += putstring(buffer:signature);
  1600.  
  1601.   send_ssh_packet(socket:socket, payload:payload, code:raw_int8(i:50));
  1602.  
  1603.   # code 60 (SSH_MSG_USERAUTH_PK_OK)
  1604.   payload = recv_ssh_packet(socket:socket);
  1605.   if ((ord(payload[0]) == 52) || (ord(payload[0]) == 60))
  1606.      authenticated = 1;
  1607.  
  1608.   if (!authenticated)
  1609.   {
  1610.     payload = "Public key authentication failed.";
  1611.     if (password)
  1612.     {
  1613.       payload += '
  1614. It seems you provided both public/private keys and password.
  1615. In this case Nessus only use your public and private keys.
  1616. Nessus did not try both. As password authentication is
  1617. vulnerable to Man-In-The-Middle attack, that implies your keys
  1618. are useless (a "malicious server" will just reject your public
  1619. key authentication and accept any provided password).
  1620. ';
  1621.     }
  1622.     set_ssh_error(msg:payload);
  1623.  
  1624.     return -1;
  1625.   }
  1626.  }
  1627.  
  1628.  # all is ok, user is authenticated
  1629.  return 0;
  1630. }
  1631.  
  1632.  
  1633. #-----------------------------------------------------------------#
  1634. # Open channel                                                    #
  1635. #-----------------------------------------------------------------#
  1636. function ssh_open_channel(socket)
  1637. {
  1638.  local_var payload, i;
  1639.  
  1640.  if (bugged_sshd && !bugged_first)
  1641.  {
  1642.    local_channel++;
  1643.    register_int_in_kb(name:"Secret/SSH/local_channel", int:local_channel);
  1644.    if (local_channel > 10)
  1645.      return -1;
  1646.    l_window_size = 32768;
  1647.    received_size = 0;
  1648.    remote_channel = bugged_channels[local_channel];
  1649.    r_window_size = bugged_rws[local_channel];
  1650.    r_packet_size = bugged_rps[local_channel];
  1651.    register_data_in_kb(name:"Secret/SSH/remote_channel", int:remote_channel);
  1652.    return 0;
  1653.  }
  1654.  
  1655.  local_channel++;
  1656.  register_int_in_kb(name:"Secret/SSH/local_channel", int:local_channel);
  1657.  
  1658.  # session = "session"
  1659.  # initial window size = 32768
  1660.  # maximum packet size = 32768
  1661.  l_window_size = 32768;
  1662.  received_size = 0;
  1663.  payload = putstring(buffer:"session") + raw_int32(i:local_channel) +
  1664.     raw_int32(i:32768) + raw_int32(i:32768);
  1665.  
  1666.  # SSH_MSG_CHANNEL_OPEN == 90
  1667.  send_ssh_packet(socket:socket, payload:payload, code:raw_int8(i:90));
  1668.  
  1669.  # SSH_MSG_CHANNEL_OPEN_CONFIRMATION == 91 (92 == failure)
  1670.  payload = recv_ssh_packet(socket:socket);
  1671.  if (ord(payload[0]) != 91)
  1672.  {
  1673.    set_ssh_error(msg:string("Received code was not  SSH_MSG_CHANNEL_OPEN_CONFIRMATION (91). It was : " , ord(payload[0])));
  1674.    return -1;
  1675.  }
  1676.  
  1677.  remote_channel = ntol(buffer:payload, begin:5);
  1678.  register_int_in_kb(name:"Secret/SSH/remote_channel", int:remote_channel);
  1679.  r_window_size = ntol(buffer:payload, begin:9);
  1680.  r_packet_size = ntol(buffer:payload, begin:13);
  1681.  
  1682.  # For bugged channel like Sun_SSH_1.0 we create 10 channels at startup 
  1683.  # Sun_SSH supports only 10 channels at the same time.
  1684.  if (bugged_sshd)
  1685.  {
  1686.    bugged_first = 0;
  1687.    register_int_in_kb(int:bugged_first, name:"Secret/SSH/bugged_first");
  1688.    bugged_channels[0] = raw_string (0x00, 0x00, 0x00, 0x00);
  1689.    bugged_rws[0] = raw_string (0x00, 0x00, 0x00, 0x00);
  1690.    bugged_rps[0] = raw_string (0x00, 0x00, 0x00, 0x00);
  1691.    bugged_channels[local_channel] = remote_channel;
  1692.    for (i=local_channel+1; i < 11; i++)
  1693.    {
  1694.       payload = putstring(buffer:"session") + raw_int32(i:i) +
  1695.       raw_int32(i:32768) + raw_int32(i:32768);
  1696.  
  1697.       send_ssh_packet(socket:socket, payload:payload, code:raw_int8(i:90));
  1698.  
  1699.       payload = recv_ssh_packet(socket:socket);
  1700.       if (ord(payload[0]) != 91)
  1701.       {
  1702.         set_ssh_error(msg:string("Received code was not  SSH_MSG_CHANNEL_OPEN_CONFIRMATION (91). It was : " , ord(payload[0])));
  1703.         return -1;
  1704.       }
  1705.  
  1706.       bugged_channels[i] = ntol(buffer:payload, begin:5);
  1707.       bugged_rws[i] = ntol(buffer:payload, begin:9);
  1708.       bugged_rps[i] = ntol(buffer:payload, begin:13);
  1709.    }
  1710.  
  1711.    register_intarray_in_kb(array:bugged_channels, name:"Secret/SSH/bugged_channels");
  1712.    register_intarray_in_kb(array:bugged_rws, name:"Secret/SSH/bugged_rws");
  1713.    register_intarray_in_kb(array:bugged_rps, name:"Secret/SSH/bugged_rps");
  1714.  }
  1715.  
  1716.  # all is ok, user is authenticated
  1717.  return 0;
  1718.  
  1719. }
  1720.  
  1721. #-----------------------------------------------------------------#
  1722. # Close channel                                                   #
  1723. #-----------------------------------------------------------------#
  1724. function ssh_close_channel(socket,end)
  1725. {
  1726.  local_var payload;
  1727.  
  1728.  # session = "session"
  1729.  # sender channel = 4444  / should we try different number on failure ?
  1730.  # initial window size = 32768
  1731.  # maximum packet size = 32768
  1732.  payload = raw_int32(i:remote_channel);
  1733.  
  1734.  # SSH_MSG_CHANNEL_CLOSE == 97
  1735.  send_ssh_packet(socket:socket, payload:payload, code:raw_int8(i:97));
  1736.  
  1737.  if (!end)
  1738.  {
  1739.    # SSH_MSG_CHANNEL_CLOSE == 97
  1740.    payload = recv_ssh_packet(socket:socket);
  1741.    while((ord(payload[0]) != 97) && (ord(payload[0]) != 0))
  1742.      payload = recv_ssh_packet(socket:socket);
  1743.  
  1744.    if (ord(payload[0]) != 97)
  1745.    {
  1746.      set_ssh_error(msg:string( "Received code was not  SSH_MSG_CHANNEL_CLOSE (97). It was : " , ord(payload[0])));
  1747.      return -1;
  1748.    }
  1749.  }
  1750.  
  1751.  # all is ok, user is authenticated
  1752.  return 0;
  1753.  
  1754. }
  1755.  
  1756.  
  1757. #-----------------------------------------------------------------#
  1758. # Login to SSH server                                             #
  1759. #-----------------------------------------------------------------#
  1760. function ssh_login(socket, login, password, pub, priv, passphrase)
  1761. {
  1762.  local_var server_user, ret;
  1763.  
  1764.  server_user = tolower(login);
  1765.  
  1766.  init();
  1767.  
  1768.  # Exchange protocol version identification strings with the server.
  1769.  server_version = ssh_exchange_identification(socket:socket);
  1770.  if (!server_version)
  1771.   return -1;
  1772.  
  1773.  _ssh_server_version = server_version;
  1774.  
  1775.  # key exchange
  1776.  # authenticate user
  1777.  ret = ssh_kex2(socket:socket, server_version:server_version);
  1778.  if (ret != 0)
  1779.    return -1;
  1780.  
  1781.  ret = ssh_userauth2(socket:socket, server_user:server_user, password:password, pub:pub, priv:priv, passphrase:passphrase);  
  1782.  if (ret != 0)
  1783.    return -1;
  1784.  
  1785.  # all is ok
  1786.  return 0;
  1787. }
  1788.  
  1789.  
  1790. #-----------------------------------------------------------------#
  1791. # Return size we can send on the channel and in the packet        #
  1792. #-----------------------------------------------------------------#
  1793. function get_data_size()
  1794. {
  1795.  local_var len;
  1796.  
  1797.  if (r_window_size <= r_packet_size)
  1798.     len = r_window_size;
  1799.  else
  1800.     len = r_packet_size;
  1801.  
  1802.  # packet option ~= 50 bytes
  1803.  len -= 50;
  1804.  
  1805.  # Remote server has not reajusted his window 
  1806.  if (len <= 0)
  1807.     return -1;
  1808.  
  1809.  return len;
  1810. }
  1811.  
  1812.  
  1813. #-----------------------------------------------------------------#
  1814. # Update Window channel size on SSH server                        #
  1815. #-----------------------------------------------------------------#
  1816. function update_window_size(socket,size)
  1817. {
  1818.  local_var len;
  1819.  
  1820.  l_window_size -= size;
  1821.  received_size += size;
  1822.  
  1823.  # Maximum allocated memory is 20 MB
  1824.  # A correct server will send 32768 bytes packet. So we stop before
  1825.  # to get data.
  1826.  # A non standard server will just be stopped by nessusd.
  1827.  if (received_size > 19000000)
  1828.    return -1;
  1829.  
  1830.  if (l_window_size < 1000)
  1831.  {
  1832.    len = 32768 - l_window_size;
  1833.    payload = raw_int32(i:remote_channel) + raw_int32(i:len);
  1834.  
  1835.    # SSH_MSG_CHANNEL_WINDOW_ADJUST == 93
  1836.    send_ssh_packet(socket:socket, payload:payload, code:raw_int8(i:93));
  1837.  
  1838.    l_window_size += len;   
  1839.  }
  1840.  
  1841.  return 0;
  1842. }
  1843.  
  1844.  
  1845.  
  1846. #-----------------------------------------------------------------#
  1847. # Execute command on SSH server                                   #
  1848. #-----------------------------------------------------------------#
  1849. function ssh_cmd(socket,cmd,timeout)
  1850. {
  1851.  local_var payload, ret, tempbuf, end, cret;
  1852.  
  1853.  # Flash error buffer
  1854.  _ssh_cmd_error = "";
  1855.  
  1856.  # Open channel
  1857.  ret = ssh_open_channel(socket:socket);
  1858.  if (ret != 0)
  1859.  {
  1860.    _ssh_cmd_error = "Nessus failed to open a new SSH channel. " + get_ssh_error();
  1861.    return NULL;
  1862.  }
  1863.  
  1864.  payload = raw_int32(i:remote_channel) + putstring(buffer:"exec") + raw_int8(i:0) +
  1865.      putstring(buffer:cmd);
  1866.  
  1867.  # SSH_MSG_CHANNEL_REQUEST == 98
  1868.  send_ssh_packet(socket:socket, payload:payload, code:raw_int8(i:98));
  1869.  
  1870.  ret = NULL;
  1871.  
  1872.  # SSH_MSG_CHANNEL_SUCCESS == 99
  1873.  # while for previous useless messages (SSH_MSG_CHANNEL_WINDOW_ADJUST, ...)
  1874.  payload = recv_ssh_packet(socket:socket, timeout:timeout);
  1875.  while((ord(payload[0]) == 93) || (ord(payload[0]) == 95) || (ord(payload[0])  == 98))
  1876.  {
  1877.   if (ord(payload[0]) == 95)
  1878.   {
  1879.     payload = getstring(buffer:payload, pos:9);
  1880.     _ssh_cmd_error += payload;
  1881.     val = update_window_size(socket:socket,size:strlen(payload));
  1882.     if (val != 0)
  1883.       break;
  1884.   }
  1885.   payload = recv_ssh_packet(socket:socket, timeout:timeout);
  1886.  }
  1887.  
  1888.  while ((ord(payload[0]) != 97) && (ord(payload[0]) != 0))
  1889.  {
  1890.   if (ord(payload[0]) == 98)
  1891.   {
  1892.     payload = getstring(buffer:payload, pos:5);
  1893.     if ("exit-status" >!< payload)
  1894.       break;
  1895.   }
  1896.   else if ((ord(payload[0]) == 94) || (ord(payload[0]) == 95))
  1897.   {
  1898.     tempbuf = getstring(buffer:payload, pos:5);
  1899.     if (ord(payload[0]) == 94)
  1900.     {
  1901.       ret += tempbuf;
  1902.     }
  1903.     val = update_window_size(socket:socket,size:strlen(tempbuf));
  1904.     if (val != 0)
  1905.     {
  1906.       break;
  1907.     }
  1908.   }
  1909.   payload = recv_ssh_packet(socket:socket, timeout:timeout);
  1910.  }
  1911.  
  1912.  end = 0;
  1913.  if (ord(payload[0]) == 97)
  1914.    end = 1;
  1915.  
  1916.  # Close channel
  1917.  cret = ssh_close_channel(socket:socket, end:end);
  1918.  if (cret != 0)
  1919.  {
  1920.    _ssh_cmd_error = "Nessus failed to close SSH channel. " + get_ssh_error();
  1921.    return NULL;
  1922.  }
  1923.  
  1924.  
  1925.  return ret;
  1926.  
  1927. }
  1928.  
  1929.  
  1930. #-----------------------------------------------------------------#
  1931. # Return errors happended during ssh_cmd()                        #
  1932. #-----------------------------------------------------------------#
  1933. function ssh_cmd_error()
  1934. {
  1935.  return _ssh_cmd_error;
  1936. }
  1937.  
  1938.  
  1939.  
  1940. #------------------------------------------------------------------#
  1941. # Connection re-use                                                #
  1942. #------------------------------------------------------------------#
  1943.  
  1944. # Internal
  1945. function reuse_connection_init()
  1946. {
  1947.  _reuse_connection = 1;
  1948.  seqn_w = load_int_from_kb(name:"Secret/SSH/seqn_w");
  1949.  seqn_r = load_int_from_kb(name:"Secret/SSH/seqn_r");
  1950.  local_channel = load_int_from_kb(name:"Secret/SSH/local_channel");
  1951.  session_id = load_data_from_kb(name:"Secret/SSH/session_id");
  1952.  remote_channel = load_int_from_kb(name:"Secret/SSH/remote_channel");
  1953.  enc_keys = load_array_from_kb(name:"Secret/SSH/enc_keys"); 
  1954.  dh_pub = load_data_from_kb(name:"Secret/SSH/dh_pub"); 
  1955.  dh_priv = load_data_from_kb(name:"Secret/SSH/dh_priv");
  1956.  bugged_sshd = load_int_from_kb(name:"Secret/SSH/bugged_sshd");
  1957.  if (bugged_sshd)
  1958.  {
  1959.    bugged_channels = load_intarray_from_kb(name:"Secret/SSH/bugged_channels"); 
  1960.    bugged_rws = load_intarray_from_kb(name:"Secret/SSH/bugged_rws"); 
  1961.    bugged_rps = load_intarray_from_kb(name:"Secret/SSH/bugged_rps"); 
  1962.    bugged_first = load_int_from_kb(name:"Secret/SSH/bugged_first"); 
  1963.  }
  1964.  if ( isnull(enc_keys) || isnull(dh_pub) || isnull(dh_priv) || isnull(session_id) ) return -1;
  1965.  return 0;
  1966. }
  1967.  
  1968.  
  1969. # Returns a socket to an already established connection 
  1970. function ssh_reuse_connection()
  1971. {
  1972.  local_var soc;
  1973.  
  1974.  if ( ! defined_func("shared_socket_acquire") ) 
  1975.     return 0;
  1976.  
  1977.  if ( reuse_connection_init() < 0 )
  1978.     {
  1979.     _reuse_connection = 0;
  1980.     return 0;
  1981.     }
  1982.  
  1983.  soc = shared_socket_acquire("Secret/SSH/socket");
  1984.  if ( soc == NULL ) 
  1985.   {
  1986.   _reuse_connection = 0;
  1987.   return 0;
  1988.   }
  1989.  else 
  1990.   return soc;
  1991. }
  1992.  
  1993.  
  1994. #
  1995. # Release the shared SSH connection so that another script can write to
  1996. # it
  1997. #
  1998. function ssh_close_connection()
  1999. {
  2000.  if ( _reuse_connection ) shared_socket_release("Secret/SSH/socket");
  2001. }
  2002.  
  2003.  
  2004.  
  2005. function ssh_login_or_reuse_connection()
  2006. {
  2007.  local_var soc;
  2008.  local_var login, password, pub, priv, passphrase;
  2009.  
  2010.  
  2011.  soc = ssh_reuse_connection();
  2012.  if ( soc > 0 ) return soc;
  2013.  
  2014.  login = kb_ssh_login();
  2015.  password = kb_ssh_password();
  2016.  pub = kb_ssh_publickey();
  2017.  priv = kb_ssh_privatekey();
  2018.  passphrase = kb_ssh_passphrase();
  2019.  
  2020.  
  2021.  if ( ! login || (! password &&  (! pub || ! priv))) return 0;
  2022.  
  2023.  
  2024.  soc = open_sock_tcp(kb_ssh_transport());
  2025.  if ( ! soc ) return 0;
  2026.  _reuse_connection = 1;
  2027.  if ( ssh_login(socket:soc, login:login, password:password, pub:pub, priv:priv, passphrase:passphrase) != 0 )
  2028.  {
  2029.   close(soc);
  2030.   return 0;
  2031.  }
  2032.  
  2033.  shared_socket_register(name:"Secret/SSH/socket", socket:soc);
  2034.  return soc;
  2035. }
  2036.